#lang typed/racket

;; Typed interface to WebSockets


(require typed/web-server/http
         typed/net/url)
(require/typed/provide
    net/rfc6455
  ;; TODO: differentiate between open and closed sockets?
  ;; opaque types ~~ abstract types w/ contracts
  [#:opaque WS ws-conn?]
  [ws-idle-timeout (Parameterof Number)]
  [ws-connect (->* (url) ;;; ws-url or wss-url
                   (#:headers header
                    #:protocol (U 'rfc6455 'hybi00))
                   WS)]
  [ws-recv-evt (->* (WS)
                    (#:payload-type (U 'auto 'text 'binary))
                    (Evtof (U String Bytes EOF)))]
  [ws-send! (->* (WS
                  (U String Bytes))
                 (#:final-fragment? Boolean
                  #:payload-type (U 'continuation 'text 'binary)
                  #:flush? Boolean)
                 Void)]
  [ws-close! (->* (WS)
                  (#:status Integer
                   #:reason String)
                  Void)]
  [ws-conn-closed? (-> WS Boolean)]
  [ws-conn-close-status (-> WS (U Number False))]
  [ws-conn-close-reason (-> WS (U String False))]
)
